package cytargetlinker.conversion;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import org.bridgedb.DataSource;
import org.bridgedb.IDMapper;
import org.bridgedb.IDMapperException;
import org.bridgedb.IDMapperStack;
import org.bridgedb.Xref;
import org.bridgedb.bio.BioDataSource;

import cytargetlinker.conversion.graph.Graph;
import cytargetlinker.conversion.graph.Graph.Node;

public class Utils {

	
	public static Node createNode(Graph graph, String id, String sysCodeIn, List<String> sysCodeOut, Map<String, String> attr, IDMapper mapper) {
		Node node = graph.addNode(id);
		node.appendAttribute("identifiers", mapIds(mapper, id, sysCodeIn, sysCodeOut));
		
		for(String str : attr.keySet()) {
			node.appendAttribute(str, attr.get(str));
		}
		
		return node;
	}
	
	public static Node createNode(Graph graph, String id, Map<String, String> attr) {
		Node node = graph.addNode(id);
		node.appendAttribute("identifiers", "[" + id + "]");
		
		for(String str : attr.keySet()) {
			node.appendAttribute(str, attr.get(str));
		}
		
		return node;
	}
	
	public static void setUpLogger(Logger log, File in, boolean append) throws SecurityException, IOException {
		FileHandler fh = new FileHandler(in.getAbsolutePath() + ".log", append);
	    log.addHandler(fh);
	    log.setLevel(Level.ALL);
	    SimpleFormatter formatter = new SimpleFormatter();
	    fh.setFormatter(formatter);
	}
	
	private static String mapIds(IDMapper mapper, String id, String sysCodeIn, List<String> sysCodeOut) {
		List<String> list = new ArrayList<String>();
		if(id.contains(".")) {
			int pos = id.indexOf(".");
			id = id.substring(0, pos);
		}
		Xref srcRef = new Xref(id, DataSource.getBySystemCode(sysCodeIn));
		list.add(id);
		for(String sysCode : sysCodeOut) {
			try {
				Set<Xref> result = mapper.mapID(srcRef, DataSource.getBySystemCode(sysCode));
				for(Xref x : result) {
					if(!list.contains(x.getId())) {
						list.add(x.getId());
					}
				}
			} catch (IDMapperException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		String identifiers = "[";
		
		for(String s : list) {
			identifiers = identifiers + s;
			if(list.indexOf(s) < list.size()) identifiers = identifiers + ",";
		}
		identifiers = identifiers + "]";
	
		return identifiers;
	}
	
	public static IDMapperStack initIDMapper(String bridgeDbSource, String bridgeDbTarget) {
		if (bridgeDbSource != null || bridgeDbTarget != null) {
			BioDataSource.init();

			try {
				Class.forName("org.bridgedb.rdb.IDMapperRdb");
			} catch (ClassNotFoundException ex) {
				return null;
			}

			try {
				IDMapperStack gdb = new IDMapperStack();
				if (bridgeDbSource != null) {
					File file = new File(bridgeDbSource);
					if (file.exists()) {
						gdb.addIDMapper("idmapper-pgdb:" + file.getAbsolutePath());
					}
				}
				if (bridgeDbTarget != null) {
					File file = new File(bridgeDbTarget);
					if (file.exists()) {
						gdb.addIDMapper("idmapper-pgdb:" + file.getAbsolutePath());
					}
				}
				if(gdb.getSize() == 0) {
					return null;
				}
				gdb.setTransitive(true);
				return gdb;
			} catch (IDMapperException e) {
				return null;
			}
		}
		return null;
	}
	
}
